package com.service.atm;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import com.bpms.common.Base64;
import com.bpms.common.CommonUtil;
import com.bpms.common.Constant;
import com.bpms.common.JdbcWorker;
import com.bpms.common.VO;
import com.bpms.common.VOList;
import com.bpms.eai.ISyncComm;
import com.bpms.esb.IService;
import com.service.uai.engine.comm.AccountQueryClient;

/**
 * 发送交易信息到集中作业管理中心<br>
 * 使用定时任务调用发送
 * 
 * @author menlin
 * 
 */
public class Send__queryaccount_request  implements IService {

	private JdbcWorker jw;
	private static final int pageSize = 50;

	@Override
	public VO exec(VO arg) {
		VO r = new VO();
		try {
			jw = new JdbcWorker();
			r.voType = "ATM.Send__queryaccount_request_answer";
			// 查询需要发送的数据（已经完成交易的支票单据，对应的进账单也已经保存到ATMP端）
			Vector<VO> v = this.getAmmo();
			if (v != null && 0 < v.size()) {
				for (VO vo : v) {
					boolean br = false; // 发送成功标识
					// 发送数据
					String rbiz = send1001(vo);
					if (rbiz != null) {
						if (send1002(vo, rbiz)) {
							// 成功标识改为true
							br = true; 
							// 修改状态
							this.updateFlag(vo.getAttr("INSTANCEID"), Constant.CM_DJB_FLAG_CLOSE);
							// 删除P端支票和进账单影像
							this.delImg(vo);
						}
					} 
					if (!br) // 失败修改状态为8
						this.updateFlag(vo.getAttr("INSTANCEID"), Constant.CM_DJB_FLAG_FAIL);
				}
			}
			r.setAttr("msg", "complete");
			return r;
		} catch (Exception e) {
			CommonUtil.error("Send__queryaccount_request 发送集中作业管理中心发生异常 exception", e);
			return null;
		} 
	}



	/**
	 * 向集中作业管理中心发送进账单数据
	 * @param vo 票据信息	
	 * @param biz 交易码 1002
	 * @return boolean 是否发送成功
	 * @throws Exception
	 */
	private boolean send1002(VO vo, String rbiz) throws Exception{
		ISyncComm syncComm = new AccountQueryClient();
		// 获取待发送数据
		byte[] buffer = this.packResult1002(vo, rbiz);
		// 发送数据
		byte[] resultBuffer = syncComm.sendBuffer(buffer);
		// 解析回执并修改状态标示
		if (resultBuffer != null) {
			String r = new String(resultBuffer);
			int i = r.indexOf("R001");
			int len = Integer.parseInt(r.substring(i - 8, i));
			String r001 = r.substring(i+4, i + 4 +len);
			return "0000".equals(r001);
		}
		return false;
	}
	/**
	 * 向集中作业管理中心发送支票数据
	 * @param vo 票据信息	
	 * @param type 交易码 1001
	 * @return boolean 是否发送成功
	 * @throws Exception
	 */
	private String send1001(VO vo) throws Exception{
		ISyncComm syncComm = new AccountQueryClient();
		// 获取待发送数据
		byte[] buffer = this.packResult1001(vo);
		// 发送数据
		byte[] resultBuffer = syncComm.sendBuffer(buffer);
		if (resultBuffer != null) {
			String r = new String(resultBuffer);
			int i = r.indexOf("R001");
			int len = Integer.parseInt(r.substring(i - 8, i));
			String r001 = r.substring(i+4, i + 4 +len);
			if ("0000".equals(r001)) {
				int ir003 = r.indexOf("R003");
				int r003Len = Integer.parseInt(r.substring(ir003 - 8, ir003));
				String r003 = r.substring(ir003+4, ir003 + 4 +r003Len);
				return r003;
			}
		}
		return null;
	}
	
	/**
	 * 删除P端影像
	 * @param vo
	 */
	private void delImg(VO vo){
		// 1.获取需要删除影像路径集合
		List<String> list = new ArrayList<String>();
		list.add(vo.getAttr("IMAGE1"));
		list.add(vo.getAttr("IMAGE2"));
		list.add(vo.getAttr("IMAGE1").replace("-1001-", "-1002-"));
		list.add(vo.getAttr("IMAGE2").replace("-1001-", "-1002-"));
		// 2.执行删除
		for (String string : list) {
			File file = new File(string);
			if (file.exists())
				file.delete();
		}
	}
	
	/**
	 * 拼装1001交易报文
	 * @param vo
	 * @return byte[]
	 * @throws Exception 
	 */
	private byte[] packResult1001(VO vo) throws Exception{
		StringBuffer b = new StringBuffer(1000000);
		// 报文头
		b.append("00000000"); // 流水号
		b.append("00000000"); // 交易报文总长度
		b.append("1001"); // 交易码
		b.append("0000");
		// 报文体
		String DEVICENO = vo.getAttr("DEVICENO"); // 1001 设备号
		b.append(String.format("%08d", DEVICENO.getBytes("gb2312").length) + "1001" +DEVICENO);
		String NETNUM = vo.getAttr("NETNUM"); // 1002 网点号
		b.append(String.format("%08d", NETNUM.getBytes("gb2312").length) + "1002" + NETNUM);
		String CERTNUM = vo.getAttr("CERTNUM"); // 1003 认证码 《加字段》
		b.append(String.format("%08d", CERTNUM.getBytes("gb2312").length) + "1003" + CERTNUM);
		String DATETIME = vo.getAttr("DATETIME"); // 1004 时间日期 《加字段》
		b.append(String.format("%08d", DATETIME.getBytes("gb2312").length) + "1004" + DATETIME);
		String TRANTYPE = vo.getAttr("TRANTYPE"); // 1005 业务类型
		b.append(String.format("%08d", TRANTYPE.getBytes("gb2312").length) + "1005" +TRANTYPE);
		String LAUNCHSITE = vo.getAttr("LAUNCHSITE"); // 1006 发起网点号
		b.append(String.format("%08d", LAUNCHSITE.getBytes("gb2312").length) + "1006" +LAUNCHSITE);
		
		String PAYEEBANK = vo.getAttr("PAYEEBANK"); //收款人开户行 1007
		b.append(String.format("%08d", PAYEEBANK.getBytes("gb2312").length) + "1007" +PAYEEBANK);
		String DRAWEEBANK = vo.getAttr("DRAWEEBANK"); // 1008 付款人开户行
		b.append(String.format("%08d", DRAWEEBANK.getBytes("gb2312").length) + "1008" +DRAWEEBANK);
		
		String PAYINGMARK = vo.getAttr("PAYINGMARK"); // 1009 首付款标识
		b.append(String.format("%08d", PAYINGMARK.getBytes("gb2312").length) + "1009" +PAYINGMARK);
		String BEARERTYPE = vo.getAttr("BEARERTYPE"); // 1010 持票人类型
		b.append(String.format("%08d", BEARERTYPE.getBytes("gb2312").length) + "1010" +BEARERTYPE);
		String IDCARD = vo.getAttr("IDCARD"); // 1011 身份证号码  《加字段》
		b.append(String.format("%08d", IDCARD.getBytes("gb2312").length) + "1011" + IDCARD);
		String IDNAME = vo.getAttr("IDNAME"); // 1012 身份证名字  《加字段》
		b.append(String.format("%08d", IDNAME.getBytes("gb2312").length) + "1012" + IDNAME);
		String ISPASSWORD = vo.getAttr("ISPASSWORD"); // 1013 是否支付密码 《加字段》
		b.append(String.format("%08d", ISPASSWORD.getBytes("gb2312").length) + "1013" + ISPASSWORD);
		String SYSTEMTYPE = vo.getAttr("SYSTEMTYPE"); // 1014 对应集中处理系统业务类型 《加字段》
		b.append(String.format("%08d", SYSTEMTYPE.getBytes("gb2312").length) + "1014" + SYSTEMTYPE);
		String PHONENUMBER = vo.getAttr("PHONENUMBER"); // 1015 联系电话 《加字段》
		b.append(String.format("%08d", PHONENUMBER.getBytes("gb2312").length) + "1015" + PHONENUMBER);
		// 1016 二维码校验标志和底纹验证结果两个都通过发送Y其他情况N
		String CHECKMARKRESULT = vo.getAttr("CHECKMARKRESULT")== null ? "N" : vo.getAttr("CHECKMARKRESULT");
		String DIWENCHECK = vo.getAttr("DIWENCHECK") == null ? "N" : vo.getAttr("DIWENCHECK"); 
		boolean temp = ("Y".equals(CHECKMARKRESULT) && "Y".equals(DIWENCHECK));
		b.append("000000011016" + (temp ? "Y" : "N"));
		// 1017 是否附行式机具 Y为是， N为否
		boolean isInBank = DEVICENO.startsWith("3");
		b.append("000000011017" + (isInBank ? "N" : "Y"));
		String BILLNO = vo.getAttr("BILLNO"); // 凭证编号
		b.append(String.format("%08d", BILLNO.getBytes("gb2312").length) + "1018" + BILLNO);
		// 1019 图码数据 二维码
		String QUICKMARK = vo.getAttr("QUICKMARK"); 
		b.append(String.format("%08d", QUICKMARK.getBytes("gb2312").length) + "1019" + QUICKMARK);
		// 1020 影像张数
		b.append("0000000110202");
//		// 1021 当前上传的是第几张影像
//		b.append("0000000110211");
//		// 1022 票据底纹是否通过 
//		String DIWENCHECK = vo.getAttr("DIWENCHECK") == null ? "N" : vo.getAttr("DIWENCHECK"); 
//		b.append("000000011022" + DIWENCHECK);
		// 第一张图片
		String img1 = getImgBase64(vo.getAttr("IMAGE1"));
		b.append(String.format("%08d", img1.getBytes("gb2312").length) + "T001" + img1);
		// 第二张图片
		String img2 = getImgBase64(vo.getAttr("IMAGE2"));
		b.append(String.format("%08d", img2.getBytes("gb2312").length) + "T002" + img2);
		int bodyLen = b.toString().getBytes("gb2312").length;
		// 报文体总长度
		b.replace(8, 16, String.format("%08d", bodyLen - 24));
		// 报文总长度
		b.insert(0, String.format("%08d", bodyLen));
//		CommonUtil.debug(b.toString());
		return b.toString().getBytes("gb2312");
	}
	
	/**
	 * 拼装1002交易报文
	 * @param vo
	 * @return
	 * @throws Exception 
	 */
	private byte[] packResult1002(VO vo,String rbiz) throws Exception{
		StringBuffer b = new StringBuffer(1000000);
		// 报文头
		b.append("00000000"); // 流水号
		b.append("00000000"); // 交易报文总长度
		b.append("1002"); // 交易码
		b.append("0000");
		// 报文体
//		String BIZID = vo.getAttr("BIZID"); // 1000 流水号
		b.append(String.format("%08d", rbiz.getBytes("gb2312").length) + "1000" +rbiz);
		String DEVICENO = vo.getAttr("DEVICENO"); // 1001 设备号
		b.append(String.format("%08d", DEVICENO.getBytes("gb2312").length) + "1001" +DEVICENO);
		String NETNUM = vo.getAttr("NETNUM"); // 1002 网点号
		b.append(String.format("%08d", NETNUM.getBytes("gb2312").length) + "1002" + NETNUM);
		String CERTNUM = vo.getAttr("CERTNUM"); // 1003 认证码 《加字段》
		b.append(String.format("%08d", CERTNUM.getBytes("gb2312").length) + "1003" + CERTNUM);
		String DATETIME = vo.getAttr("DATETIME"); // 1004 时间日期 《加字段》
		b.append(String.format("%08d", DATETIME.getBytes("gb2312").length) + "1004" + DATETIME);
		String TRANTYPE = vo.getAttr("TRANTYPE"); // 1005 业务类型
		b.append(String.format("%08d", TRANTYPE.getBytes("gb2312").length) + "1005" +TRANTYPE);
		String LAUNCHSITE = vo.getAttr("LAUNCHSITE"); // 1006 发起网点号
		b.append(String.format("%08d", LAUNCHSITE.getBytes("gb2312").length) + "1006" +LAUNCHSITE);
		
		String PAYEEBANK = vo.getAttr("PAYEEBANK"); //收款人开户行 1007
		b.append(String.format("%08d", PAYEEBANK.getBytes("gb2312").length) + "1007" +PAYEEBANK);
		String DRAWEEBANK = vo.getAttr("DRAWEEBANK"); // 1008 付款人开户行
		b.append(String.format("%08d", DRAWEEBANK.getBytes("gb2312").length) + "1008" +DRAWEEBANK);
		
		String PAYINGMARK = vo.getAttr("PAYINGMARK"); // 1009 首付款标识
		b.append(String.format("%08d", PAYINGMARK.getBytes("gb2312").length) + "1009" +PAYINGMARK);
		String BEARERTYPE = vo.getAttr("BEARERTYPE"); // 1010 持票人类型
		b.append(String.format("%08d", BEARERTYPE.getBytes("gb2312").length) + "1010" +BEARERTYPE);
		String IDCARD = vo.getAttr("IDCARD"); // 1011 身份证号码  《加字段》
		b.append(String.format("%08d", IDCARD.getBytes("gb2312").length) + "1011" + IDCARD);
		String IDNAME = vo.getAttr("IDNAME"); // 1012 身份证名字  《加字段》
		b.append(String.format("%08d", IDNAME.getBytes("gb2312").length) + "1012" + IDNAME);
		String ISPASSWORD = vo.getAttr("ISPASSWORD"); // 1013 是否支付密码 《加字段》
		b.append(String.format("%08d", ISPASSWORD.getBytes("gb2312").length) + "1013" + ISPASSWORD);
		String SYSTEMTYPE = vo.getAttr("SYSTEMTYPE"); // 1014 对应集中处理系统业务类型 《加字段》
		b.append(String.format("%08d", SYSTEMTYPE.getBytes("gb2312").length) + "1014" + SYSTEMTYPE);
		String PHONENUMBER = vo.getAttr("PHONENUMBER"); // 1015 联系电话 《加字段》
		b.append(String.format("%08d", PHONENUMBER.getBytes("gb2312").length) + "1015" + PHONENUMBER);
		// 1016 二维码校验标志 Y为通过，N为未通过
		b.append("000000011016Y");
		String AMOUNT = vo.getAttr("AMOUNT");// 1017 金额
		b.append(String.format("%08d", AMOUNT.getBytes("gb2312").length) + "1017" + AMOUNT);
		String BILLNO = vo.getAttr("BILLNO"); // 凭证编号
		b.append(String.format("%08d", BILLNO.getBytes("gb2312").length) + "1018" + BILLNO);
		// 1019 影像序号
		b.append("0000000110192");
//		String QUICKMARK = vo.getAttr("QUICKMARK"); 
//		b.append(String.format("%08d", QUICKMARK.getBytes("gb2312").length) + "1019" + QUICKMARK);
		// 1020 影像张数
		b.append("0000000110202");
//		// 1021 当前上传的是第几张影像
//		b.append("0000000110211");
		// 第一张图片
		String img1 = getImgBase64(vo.getAttr("IMAGE1").replace("-1001-", "-1002-"));
		if (img1 != null)
			b.append(String.format("%08d", img1.getBytes("gb2312").length) + "T001" + img1);
		else 
			b.replace(b.length(), b.length(), "0");
		// 第二张图片
		String img2 = getImgBase64(vo.getAttr("IMAGE2").replace("-1001-", "-1002-"));
		if (img2 != null) 
			b.append(String.format("%08d", img2.getBytes("gb2312").length) + "T002" + img2);
		else
			b.replace(b.length(), b.length(), "0");
		int bodyLen = b.toString().getBytes("gb2312").length;
		// 报文体总长度
		b.replace(8, 16, String.format("%08d", bodyLen - 24));
		// 报文总长度
		b.insert(0, String.format("%08d", b.toString().getBytes("gb2312").length));
		return b.toString().getBytes("gb2312");
	}
	
	/**
	 * 获取图片的base64编码
	 * @param path 图片路径
	 * @return String
	 */
	private String getImgBase64(String path){
		
		return Base64.encodeFromFile(path);
	}
	
	/**
	 * 修改发送状态
	 * 
	 * @throws Exception
	 */
	private void updateFlag(String id, String flag) throws Exception {
		StringBuffer sql = new StringBuffer(50);
		sql.append("UPDATE cm_djb SET flag='"+flag+"'  WHERE instanceid='" + id + "'");
		jw.execute(sql.toString());
	}


	/**
	 * 获取待发送单据集合10条 张支票带进账单数据
	 * @return
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	private Vector<VO> getAmmo() throws Exception{
		StringBuffer sql = new StringBuffer(100);
		sql.append("SELECT * FROM cm_djb where flag='1' order by instanceid");
		VOList list = jw.readAll(new VO(), sql.toString(), 1, pageSize);
		return list.listData;
	}
	
	
	/**
	 * java.sql.Clob 转成字符串
	 * @param clob
	 * @return String
	 * @throws Exception
	 */
//	private String clobToString(Clob clob) throws Exception {
//		if (clob == null) {
//			return null;
//		}
//		Reader inStreamDoc = clob.getCharacterStream();
//		char[] tempDoc = new char[(int) clob.length()];
//		inStreamDoc.read(tempDoc);
//		inStreamDoc.close();
//		return new String(tempDoc);
//	}
	
}
